#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

void handler(int signo)
{
    cout << "get a signo: " << signo << endl;
}

//这里是引用
void printpending(sigset_t &pending)
{
    for (int signo = 31; signo >= 1; signo--)
    {
        // sigismember函数是检测signo这个信号是否已经在我们的参数pending信号集中
        if (sigismember(&pending, signo))
        {
            cout << "1";
        }
        else
        {
            cout << "0";
        }
    }
    cout << "\n\n";
}
int main()
{
    //模拟实现屏蔽所有的信号
    // sigset_t bset, oset;
    // sigemptyset(&bset);//初始化信号集bset
    // sigemptyset(&oset);//初始化信号集oset
    // for(int i = 1; i <= 31; i++)
    // {
    //     sigaddset(&bset,i);
    // }
    // //屏蔽信号
    // sigprocmask(SIG_SETMASK, &bset, &oset);
    // sigset_t pending;
    // while(true)
    // {
    //     //2.1获取pending信号集
    //     int n = sigpending(&pending);
    //     if(n < 0)
    //     {
    //         continue;
    //     }

    //     // 2.2打印pending信号集
    //     printpending(pending);
    //     sleep(1);
    // }




    //0.对2号信号进行自定义捕捉
     signal(2,handler);

    // 1先对2号信号进行屏蔽
    sigset_t bset, oset;
    sigemptyset(&bset);//初始化信号集bset
    sigemptyset(&oset);//初始化信号集oset

    sigaddset(&bset,2);//添加2号信号到bset中

    //1.2调用系统调用，将数据设置进内核 ---屏蔽2号信号集
    //将原来的信号屏蔽集保存到oset中，然后将2号信号集屏蔽集和SIG_SETMASK进行结合
    //将2号信号屏蔽集传到block信号集中
    sigprocmask(SIG_SETMASK, &bset, &oset);

    //2.重复打印当前进程的pending信号集
    sigset_t pending;
    int cnt = 1;
    while(cnt)
    {

        //2.1获取pending信号集
        int n = sigpending(&pending);
        if(n < 0)
        {
            continue;
        }

        // 2.2打印pending信号集
        printpending(pending);

        sleep(1);
        cnt++;

        //2.3解除对pending信号集的阻塞
        if(cnt == 20)
        {
            cout <<"unblock 2 signal" << endl;
            sigprocmask(SIG_SETMASK, &oset, nullptr);
        }
    }
}